home *** CD-ROM | disk | FTP | other *** search
- ;; ====================================================================
- ;; Macros
- ;; ====================================================================
- ;; Jump if key pressed
- JKEYP MACRO key,label
- cmp byte ptr cs:_keyFlags[key+1],1
- je label
- ENDM
- ;; Jump if key not pressed
- JKEYNP MACRO key,label
- cmp byte ptr cs:_keyFlags[key+1],1
- jne label
- ENDM
-
- ;; Note that JNKEY and JKEY both modify _flKeyChanged, so you cannot
- ;; use one after the other! In other words,
- ;; JKEYNP no_key
- ;; JKEYP yes_key ;<-- this will fail
- ;; will not work like you'd think it would. The second call (JKEYP)
- ;; will not know that a key has been pressed!
- ;; Jump if no key pressed:
- JNKEY MACRO label
- cmp cs:_flKeyChanged,0
- je label
- mov cs:_flKeyChanged,0 ; <--- important!
- ENDM
- ;; Jump if key pressed:
- JKEY MACRO label
- cmp cs:_flKeyChanged,0
- mov cs:_flKeyChanged,0
- jne label
- ENDM
-
- ;; Start keyboard interrupts
- KEYB_START MACRO
- call SwapInt9
- mov cs:_flKeyChanged,0
- ENDM
-
- ;; Clear keyboard interrupts
- KEYB_END MACRO
- call SwapInt9
- ENDM
-
- ;; Credit for these routines: Steve Dollins, Brown Computer Group.
- ;; I didn't write any of the code below -- just heisted it from some
- ;; stuff that he wrote and released! Very useful keyboard routines.
- ;; Any comments prefixed SDE were added by me.
- _keyFlags dw 256 dup (0) ; SDE: since they only use 2 bits
- ; per word, this is a tradeoff,
- ; space for time
-
- oldint9_offset dw offset newint9
- oldint9_segment dw seg newint9
-
- _flKeyChanged dw 0
-
- ;-----------------------------------------------------------------------
- ; void SwapInt9( void )
- ;
- ; SwapInt9() exchanges the vector in oldint9_segment:oldint9_offset
- ; with the vector in the interrupt table for INT 9h.
- ;-----------------------------------------------------------------------
-
- SwapInt9 PROC far
- mov ax,cs
- mov ds,ax
-
- mov ax,03509h ; Get interrupt 09h
- int 21h ; return in ES:BX
-
- mov ax,oldint9_segment
- mov dx,oldint9_offset
- push ds
- mov ds,ax
- mov ax,02509h ; Set new interrupt
- int 21h ; to address in DS:DX
- pop ds
-
- mov oldint9_segment,es ; Save the old interrupt
- mov oldint9_offset,bx
- ret
- SwapInt9 ENDP
-
-
- ;-----------------------------------------------------------------------
- ; newint9 is the new keyboard interrupt (INT 9h).
- ;
- ; Reads the scan code from the keyboard and modifies the key
- ; flags table. The high byte is set to the position of the key,
- ; pressed=1, release=0. The low byte is set to 1 when the key
- ; is pressed and left unmodified when the key is released.
- ;-----------------------------------------------------------------------
- newint9 PROC far
- push ax
- push bx
- push ds
-
- mov ax,cs
- mov ds,ax
-
- JKEYNP kCTRL,not_ctrlaltdel ; SDE code
- JKEYNP kALT,not_ctrlaltdel ; To still allow ctrl-
- JKEYNP kDELETE,not_ctrlaltdel ; alt-delete. Nothing
- jmp ctrlaltdel ; worse than a total lockup!
- not_ctrlaltdel:
-
- in ax,60h ; get scan code in AL, control byte in AH
- mov bx,ax ; save a copy in BX
- xchg ah,al ; swap to get control byte in AL
- or al,80h ; clear keyboard
- out 61h,al ; of interrupt
- and al,7Fh
- out 61h,al
- mov al,20h ; send generic EOI to
- out 20h,al ; PIC
-
- and bx,0007fh ; strip all but the scan code
- shl bx,1 ; multiply by two to get our offset
-
- ; if the key was released, the high bit is set in the scan code
- bt ax,15 ; move this high bit into the carry flag
- setnc byte ptr [_keyFlags+bx+1] ; set "Is being pressed" flag
- jc short int09done ; if the key was released, we're done
- mov byte ptr [_keyFlags+bx],1 ; set "Has been pressed" flag
- mov _flKeyChanged,1 ; state of keyboard has changed
- int09done:
- mov _flKeyChanged,1 ; state of keyboard has changed
- pop ds
- pop bx
- pop ax
- iret
- ctrlaltdel: int 19h ; SDE -- added this.
- ; Allows a reboot.
- newint9 ENDP
-
- ;; Defines the current key procedure (used as a jump-through)
- kprocCur dw KprocDirect
-
- ;; This is a keyboard procedure. Normally, this would control some
- ;; sprite, or something, and the screen would follow the sprite. For
- ;; the purposes of this code, though (namely, sprite-less scrolling)
- ;; it just directly affects ScrollDX and ScrollDY.
- ;; This keyproc is inertialess, use + and - to increase speed and
- ;; the up/down/left/right keys to move directions.
- ;; Pressing K will switch to the other keyprocedure on the fly.
- ;; P pauses the screen -- note that this is just for completely
- ;; freezing the screen... it doesn't return until you let go!
-
- EVEN
- scroll_speed_x dw SCROLL_SPEED ; (defaults)
- scroll_speed_y dw SCROLL_SPEED * VIRTUAL_WIDTH ; (defaults)
- KprocDirect PROC near
- chk_leftright: mov ax,0
- JKEYNP kRIGHT,not_right
- mov ax,scroll_speed_x
- mov ScrollDX,ax
- jmp chk_updown
- not_right: JKEYNP kLEFT,not_left
- sub ax,scroll_speed_x
- mov ScrollDX,ax
- jmp chk_updown
- not_left: mov ScrollDX,ax
-
- chk_updown: mov ax,0
- JKEYNP kUP,not_up
- sub ax,scroll_speed_y
- mov ScrollDY,ax
- jmp chk_other
- not_up: JKEYNP kDOWN,not_down
- mov ax,scroll_speed_y
- mov ScrollDY,ax
- jmp chk_other
- not_down: mov ScrollDY,ax
-
- chk_other: JKEYNP kK,not_k
- mov kprocCur,KprocInertia
- not_k: JKEYNP kM,not_m
- mov bDoTransition,1
- not_m: JKEYNP kGREY_MINUS,not_minus
- cmp scroll_speed_x,1
- jle not_minus
- dec scroll_speed_x
- sub scroll_speed_y,VIRTUAL_WIDTH
- not_minus: JKEYNP kGREY_PLUS,not_plus
- cmp scroll_speed_x,16
- jge not_plus
- inc scroll_speed_x
- add scroll_speed_y,VIRTUAL_WIDTH
- not_plus:
-
- pause_key: JKEYP kP,pause_key
-
- ret
- KprocDirect ENDP
-
- ;; This keyproc has inertia, so + and - don't work.
- ;; Use up/down/left/right keys to increase speed in those directions.
- ;; Pressing K will switch to the other keyprocedure on the fly.
- ;; P pauses the screen -- note that this is just for completely
- ;; freezing the screen... it doesn't return until you let go!
- KprocInertia PROC near
- chk2_leftright: JKEYNP kRIGHT,not2_right
- cmp ScrollDX,16
- je not2_right
- inc ScrollDX
- jmp chk2_updown
- not2_right: JKEYNP kLEFT,not2_left
- cmp ScrollDX,-16
- je not2_left
- dec ScrollDX
- jmp chk2_updown
- not2_left:
-
- chk2_updown: JKEYNP kUP,not2_up
- cmp ScrollDY,-VIRTUAL_WIDTH * 16
- je not2_up
- add ScrollDY,-VIRTUAL_WIDTH
- jmp chk2_other
- not2_up: JKEYNP kDOWN,not2_down
- cmp ScrollDY,VIRTUAL_WIDTH * 16
- je not2_down
- add ScrollDY,VIRTUAL_WIDTH
- jmp chk2_other
- not2_down:
-
- chk2_other: JKEYNP kK,not2_k
- mov kprocCur,KprocDirect
- not2_k: JKEYNP kM,not2_m
- mov bDoTransition,1
- not2_m:
-
- pause2_key: JKEYP kP,pause2_key
-
- ret
- KprocInertia ENDP